home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / OldSrc / CH4 / SRC / UNSHARP.FRM (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1997-01-03  |  28.0 KB  |  877 lines

  1. VERSION 4.00
  2. Begin VB.Form UnsharpForm 
  3.    Caption         =   "Unsharp"
  4.    ClientHeight    =   4020
  5.    ClientLeft      =   840
  6.    ClientTop       =   1275
  7.    ClientWidth     =   8310
  8.    Height          =   4710
  9.    Left            =   780
  10.    LinkTopic       =   "Form1"
  11.    ScaleHeight     =   268
  12.    ScaleMode       =   3  'Pixel
  13.    ScaleWidth      =   554
  14.    Top             =   645
  15.    Width           =   8430
  16.    Begin VB.ComboBox FilterCombo 
  17.       Height          =   315
  18.       Left            =   3360
  19.       Style           =   2  'Dropdown List
  20.       TabIndex        =   11
  21.       Top             =   480
  22.       Width           =   1575
  23.    End
  24.    Begin VB.PictureBox ToSwin 
  25.       Height          =   3735
  26.       Left            =   5040
  27.       ScaleHeight     =   245
  28.       ScaleMode       =   3  'Pixel
  29.       ScaleWidth      =   197
  30.       TabIndex        =   9
  31.       Top             =   0
  32.       Width           =   3015
  33.       Begin VB.PictureBox ToPict 
  34.          AutoRedraw      =   -1  'True
  35.          AutoSize        =   -1  'True
  36.          Height          =   75
  37.          Left            =   0
  38.          MousePointer    =   2  'Cross
  39.          Picture         =   "UNSHARP.frx":0000
  40.          ScaleHeight     =   1
  41.          ScaleMode       =   3  'Pixel
  42.          ScaleWidth      =   1
  43.          TabIndex        =   10
  44.          Top             =   0
  45.          Width           =   75
  46.       End
  47.    End
  48.    Begin VB.PictureBox FromSwin 
  49.       Height          =   3735
  50.       Left            =   0
  51.       ScaleHeight     =   245
  52.       ScaleMode       =   3  'Pixel
  53.       ScaleWidth      =   197
  54.       TabIndex        =   7
  55.       Top             =   0
  56.       Width           =   3015
  57.       Begin VB.PictureBox FromPict 
  58.          AutoRedraw      =   -1  'True
  59.          AutoSize        =   -1  'True
  60.          Height          =   75
  61.          Left            =   0
  62.          MousePointer    =   2  'Cross
  63.          Picture         =   "UNSHARP.frx":0446
  64.          ScaleHeight     =   1
  65.          ScaleMode       =   3  'Pixel
  66.          ScaleWidth      =   1
  67.          TabIndex        =   8
  68.          Top             =   0
  69.          Width           =   75
  70.       End
  71.    End
  72.    Begin VB.VScrollBar ToVBar 
  73.       Height          =   3735
  74.       Left            =   8040
  75.       TabIndex        =   6
  76.       Top             =   0
  77.       Width           =   255
  78.    End
  79.    Begin VB.HScrollBar ToHBar 
  80.       Height          =   255
  81.       Left            =   5040
  82.       TabIndex        =   5
  83.       Top             =   3720
  84.       Width           =   3045
  85.    End
  86.    Begin VB.CommandButton CmdCopy 
  87.       Caption         =   "<-- Copy"
  88.       Enabled         =   0   'False
  89.       Height          =   495
  90.       Left            =   3720
  91.       TabIndex        =   4
  92.       Top             =   1920
  93.       Width           =   855
  94.    End
  95.    Begin VB.CommandButton CmdApply 
  96.       Caption         =   "Apply -->"
  97.       Enabled         =   0   'False
  98.       Height          =   495
  99.       Left            =   3720
  100.       TabIndex        =   3
  101.       Top             =   1080
  102.       Width           =   855
  103.    End
  104.    Begin VB.CheckBox ProgressCheck 
  105.       Caption         =   "Show Progress"
  106.       Height          =   255
  107.       Left            =   3360
  108.       TabIndex        =   2
  109.       Top             =   120
  110.       Width           =   1575
  111.    End
  112.    Begin VB.HScrollBar FromHBar 
  113.       Height          =   255
  114.       Left            =   0
  115.       TabIndex        =   1
  116.       Top             =   3720
  117.       Width           =   3045
  118.    End
  119.    Begin VB.VScrollBar FromVBar 
  120.       Height          =   3735
  121.       Left            =   3000
  122.       TabIndex        =   0
  123.       Top             =   0
  124.       Width           =   255
  125.    End
  126.    Begin MSComDlg.CommonDialog FileDialog 
  127.       Left            =   3960
  128.       Top             =   2880
  129.       _Version        =   65536
  130.       _ExtentX        =   847
  131.       _ExtentY        =   847
  132.       _StockProps     =   0
  133.       CancelError     =   -1  'True
  134.    End
  135.    Begin VB.Menu mnuFile 
  136.       Caption         =   "&File"
  137.       Begin VB.Menu mnuFileLoad 
  138.          Caption         =   "&Load..."
  139.          Shortcut        =   ^L
  140.       End
  141.       Begin VB.Menu mnuFileSave 
  142.          Caption         =   "&Save"
  143.          Enabled         =   0   'False
  144.          Shortcut        =   ^S
  145.       End
  146.       Begin VB.Menu mnuFileSaveAs 
  147.          Caption         =   "Save &As..."
  148.          Enabled         =   0   'False
  149.          Shortcut        =   ^A
  150.       End
  151.       Begin VB.Menu mnuFileSep1 
  152.          Caption         =   "-"
  153.       End
  154.       Begin VB.Menu mnuFileRevert 
  155.          Caption         =   "&Revert"
  156.          Enabled         =   0   'False
  157.          Shortcut        =   ^R
  158.       End
  159.       Begin VB.Menu mnuFileSep2 
  160.          Caption         =   "-"
  161.       End
  162.       Begin VB.Menu mnuFileExit 
  163.          Caption         =   "E&xit"
  164.       End
  165.    End
  166. Attribute VB_Name = "UnsharpForm"
  167. Attribute VB_Creatable = False
  168. Attribute VB_Exposed = False
  169. Option Explicit
  170. Dim SysPalSize As Integer
  171. Dim NumStaticColors As Integer
  172. Dim StaticColor1 As Integer
  173. Dim StaticColor2 As Integer
  174. Dim DataChanged As Boolean
  175. Dim FileLoaded As String
  176. Dim LogPal As Integer
  177. Dim palentry(0 To 255) As PALETTEENTRY
  178. Dim wid As Long
  179. Dim hgt As Long
  180. Dim bytes() As Byte
  181. ' ************************************************
  182. ' Put the names of the available filters in the
  183. ' filter combo box.
  184. ' ************************************************
  185. Sub LoadFilterChoices()
  186.     FilterCombo.AddItem "Low Pass 3x3"
  187.     FilterCombo.AddItem "Low Pass 5x5"
  188.     FilterCombo.AddItem "Low Pass 7x7"
  189.     FilterCombo.ListIndex = 0
  190. End Sub
  191. ' ***********************************************
  192. ' Load the control's palette so it matches the
  193. ' the system palette. Remap any of the image's
  194. ' pixels that use static colors to non-static
  195. ' colors.
  196. ' Set the following module global variables.
  197. '   LogPal      Image logical palette handle.
  198. '   palentry()  Image logical palette entries.
  199. '   wid         Width of image.
  200. '   hgt         Height of image.
  201. '   bytes(1 To wid, 1 To hgt)
  202. '               Image pixel values.
  203. ' ***********************************************
  204. Sub MatchColorPalette(pic As Control)
  205. Dim sys(0 To 255) As PALETTEENTRY
  206. Dim i As Integer
  207. Dim bm As BITMAP
  208. Dim hbm As Integer
  209. Dim status As Long
  210. Dim X As Integer
  211. Dim Y As Integer
  212. Dim clr As Integer
  213.     ' Make sure pic has the foreground palette.
  214.     pic.ZOrder
  215.     i = RealizePalette(pic.hdc)
  216.     DoEvents
  217.     ' Get the system palette entries.
  218.     i = GetSystemPaletteEntries(pic.hdc, 0, SysPalSize, sys(0))
  219.             
  220.     ' Make the logical palette as big as possible.
  221.     LogPal = pic.Picture.hPal
  222.     If ResizePalette(LogPal, SysPalSize) = 0 Then
  223.         Beep
  224.         MsgBox "Error resizing logical palette.", _
  225.             vbExclamation
  226.         Exit Sub
  227.     End If
  228.     ' Blank the non-static colors.
  229.     For i = 0 To StaticColor1
  230.         palentry(i) = sys(i)
  231.     Next i
  232.     For i = StaticColor1 + 1 To StaticColor2 - 1
  233.         With palentry(i)
  234.             .peRed = 0
  235.             .peGreen = 0
  236.             .peBlue = 0
  237.             .peFlags = PC_NOCOLLAPSE
  238.         End With
  239.     Next i
  240.     For i = StaticColor2 To 255
  241.         palentry(i) = sys(i)
  242.     Next i
  243.     i = SetPaletteEntries(LogPal, 0, SysPalSize, palentry(0))
  244.     ' Insert the non-static colors.
  245.     For i = StaticColor1 + 1 To StaticColor2 - 1
  246.         palentry(i) = sys(i)
  247.         palentry(i).peFlags = PC_NOCOLLAPSE
  248.     Next i
  249.     i = SetPaletteEntries(LogPal, StaticColor1 + 1, StaticColor2 - StaticColor1 - 1, palentry(StaticColor1 + 1))
  250.     ' Realize the new palette.
  251.     i = RealizePalette(pic.hdc)
  252.     ' Get the image pixels.
  253.     hbm = pic.Image
  254.     status = GetObject(hbm, BITMAP_SIZE, bm)
  255.     wid = bm.bmWidthBytes
  256.     hgt = bm.bmHeight
  257.     ReDim bytes(1 To wid, 1 To hgt)
  258.     status = GetBitmapBits(hbm, wid * hgt, bytes(1, 1))
  259.     ' Remap any pixels using static colors.
  260.     For Y = 1 To hgt
  261.         For X = 1 To wid
  262.             clr = bytes(X, Y)
  263.             If clr <= StaticColor1 Or clr >= StaticColor2 Then
  264.                 With sys(clr)
  265.                     bytes(X, Y) = _
  266.                         NearestNonstaticColor( _
  267.                         .peRed, .peGreen, .peBlue)
  268.                 End With
  269.             End If
  270.         Next X
  271.     Next Y
  272.     ' Update the image's pixel values.
  273.     status = SetBitmapBits(hbm, wid * hgt, bytes(1, 1))
  274.     pic.Refresh
  275. End Sub
  276. ' ***********************************************
  277. ' Load the control's palette so the non-static
  278. ' colors are grays. Map the logical palette to
  279. ' match the system palette. Convert the image to
  280. ' use the non-static grays.
  281. ' Set the following module global variables.
  282. '   LogPal      Image logical palette handle.
  283. '   palentry()  Image logical palette entries.
  284. '   wid         Width of image.
  285. '   hgt         Height of image.
  286. '   bytes(1 To wid, 1 To hgt)
  287. '               Image pixel values.
  288. ' ***********************************************
  289. Sub MatchGrayPalette(pic As Control)
  290. Dim sys(0 To 255) As PALETTEENTRY
  291. Dim i As Integer
  292. Dim bm As BITMAP
  293. Dim hbm As Integer
  294. Dim status As Long
  295. Dim X As Integer
  296. Dim Y As Integer
  297. Dim gray As Single
  298. Dim dgray As Single
  299. Dim c As Integer
  300. Dim clr As Integer
  301.     ' Make sure pic has the foreground palette.
  302.     pic.ZOrder
  303.     i = RealizePalette(pic.hdc)
  304.     DoEvents
  305.     ' Get the system palette entries.
  306.     i = GetSystemPaletteEntries(pic.hdc, 0, SysPalSize, sys(0))
  307.         
  308.     ' Get the image pixels.
  309.     hbm = pic.Image
  310.     status = GetObject(hbm, BITMAP_SIZE, bm)
  311.     wid = bm.bmWidthBytes
  312.     hgt = bm.bmHeight
  313.     ReDim bytes(1 To wid, 1 To hgt)
  314.     status = GetBitmapBits(hbm, wid * hgt, bytes(1, 1))
  315.     ' Make the logical palette as big as possible.
  316.     LogPal = pic.Picture.hPal
  317.     If ResizePalette(LogPal, SysPalSize) = 0 Then
  318.         Beep
  319.         MsgBox "Error resizing logical palette.", _
  320.             vbExclamation
  321.         Exit Sub
  322.     End If
  323.     ' Blank the non-static colors.
  324.     For i = 0 To StaticColor1
  325.         palentry(i) = sys(i)
  326.     Next i
  327.     For i = StaticColor1 + 1 To StaticColor2 - 1
  328.         With palentry(i)
  329.             .peRed = 0
  330.             .peGreen = 0
  331.             .peBlue = 0
  332.             .peFlags = PC_NOCOLLAPSE
  333.         End With
  334.     Next i
  335.     For i = StaticColor2 To 255
  336.         palentry(i) = sys(i)
  337.     Next i
  338.     i = SetPaletteEntries(LogPal, 0, SysPalSize, palentry(0))
  339.     ' Insert the non-static grays.
  340.     gray = 0
  341.     dgray = 255 / (StaticColor2 - StaticColor1 - 2)
  342.     For i = StaticColor1 + 1 To StaticColor2 - 1
  343.         c = gray
  344.         gray = gray + dgray
  345.         With palentry(i)
  346.             .peRed = c
  347.             .peGreen = c
  348.             .peBlue = c
  349.         End With
  350.     Next i
  351.     i = SetPaletteEntries(LogPal, StaticColor1 + 1, StaticColor2 - StaticColor1 - 1, palentry(StaticColor1 + 1))
  352.     ' Recreate the image using the new colors.
  353.     For Y = 1 To hgt
  354.         For X = 1 To wid
  355.             clr = bytes(X, Y)
  356.             With sys(clr)
  357.                 c = (CInt(.peRed) + .peGreen + .peBlue) / 3
  358.             End With
  359.             bytes(X, Y) = NearestNonstaticGray(c)
  360.         Next X
  361.     Next Y
  362.     status = SetBitmapBits(hbm, wid * hgt, bytes(1, 1))
  363.     ' Realize the gray palette.
  364.     i = RealizePalette(pic.hdc)
  365.     pic.Refresh
  366. End Sub
  367. ' ************************************************
  368. ' Return the index of the nonstatic gray closest
  369. ' to the given value (assuming the non-static
  370. ' colors are a gray scale created by
  371. ' MatchGrayPalette).
  372. ' ************************************************
  373. Function NearestNonstaticGray(c As Integer) As Integer
  374. Dim dgray As Single
  375.     If c < 0 Then
  376.         c = 0
  377.     ElseIf c > 255 Then
  378.         c = 255
  379.     End If
  380.     dgray = 255 / (StaticColor2 - StaticColor1 - 2)
  381.     NearestNonstaticGray = c / dgray + StaticColor1 + 1
  382. End Function
  383. ' ************************************************
  384. ' Return the index of the nonstatic color closest
  385. ' to the given color value.
  386. ' ************************************************
  387. Function NearestNonstaticColor(ByVal r As Integer, ByVal g As Integer, ByVal b As Integer) As Integer
  388. Dim best_i As Integer
  389. Dim best_dist As Long
  390. Dim dist As Long
  391. Dim dr As Long
  392. Dim dg As Long
  393. Dim db As Long
  394. Dim i As Integer
  395.     best_dist = 1000000
  396.     For i = StaticColor1 + 1 To StaticColor2 - 1
  397.         With palentry(i)
  398.             dr = r - .peRed
  399.             dg = g - .peGreen
  400.             db = b - .peBlue
  401.             dist = dr * dr + dg * dg + db * db
  402.         End With
  403.         If best_dist > dist Then
  404.             best_i = i
  405.             best_dist = dist
  406.         End If
  407.     Next i
  408.     NearestNonstaticColor = best_i
  409. End Function
  410. ' ***********************************************
  411. ' If the data has been modified, allow the user
  412. ' to save the changes or cancel the operation.
  413. ' Return True if:
  414. '   - The image data has not been changed since
  415. '       it was loaded.
  416. '   - The user saves the changes.
  417. '   - The user says not to save.
  418. ' Return False otherwise.
  419. ' ***********************************************
  420. Function DataSafe() As Boolean
  421.     DataSafe = True
  422.     ' This is done in a while loop in case the
  423.     ' user starts a save and then cancels.
  424.     Do While DataChanged
  425.         Select Case MsgBox("The data has been modified. Do you want to save the changes?", vbQuestion + vbYesNoCancel, "Data Modified")
  426.             Case vbYes
  427.                 If FileLoaded <> "" Then
  428.                     mnuFileSave_Click
  429.                 Else
  430.                     mnuFileSaveAs_Click
  431.                 End If
  432.                 DataSafe = Not DataChanged
  433.             
  434.             Case vbNo
  435.                 DataSafe = True
  436.                 Exit Do
  437.             Case vbCancel
  438.                 DataSafe = False
  439.                 Exit Do
  440.         End Select
  441.     Loop
  442. End Function
  443. ' ***********************************************
  444. ' Load the indicated file and prepare to work
  445. ' with its palette.
  446. ' ***********************************************
  447. Sub LoadFromPict(fname As String)
  448.     On Error GoTo LoadFileError
  449.     FromPict.Picture = LoadPicture(fname)
  450.         
  451.     MatchGrayPalette FromPict
  452.     ToPict.Picture = FromPict.Image
  453.     MatchGrayPalette ToPict
  454.     FromPict.Move 0, 0
  455.     ToPict.Move 0, 0
  456.     ResetScrollBars
  457.     FromSwin.ZOrder
  458.     DoEvents
  459.     ToSwin.ZOrder
  460.     DoEvents
  461.     FileLoaded = fname
  462.     Caption = "UnSharp [" & fname & "]"
  463.     mnuFileSave.Enabled = True
  464.     mnuFileSaveAs.Enabled = True
  465.     mnuFileRevert.Enabled = True
  466.     CmdApply.Enabled = True
  467.     CmdCopy.Enabled = True
  468.     DataChanged = False
  469.     Exit Sub
  470. LoadFileError:
  471.     Beep
  472.     MsgBox "Error loading file " & fname & "." & _
  473.         vbCrLf & Error$
  474.     Exit Sub
  475. End Sub
  476. ' ***********************************************
  477. ' Set the Max and LargeChange properties for the
  478. ' image scroll bars.
  479. ' ***********************************************
  480. Sub ResetScrollBars()
  481.     ' FromHBar.
  482.     FromHBar.Value = 0
  483.     If FromSwin.ScaleWidth >= FromPict.Width Then
  484.         FromHBar.Enabled = False
  485.     Else
  486.         FromHBar.Max = FromPict.Width - FromSwin.ScaleWidth
  487.         FromHBar.LargeChange = FromSwin.ScaleWidth
  488.         FromHBar.Enabled = True
  489.     End If
  490.     ' FromVBar.
  491.     FromVBar.Value = 0
  492.     If FromSwin.ScaleHeight >= FromPict.Height Then
  493.         FromVBar.Enabled = False
  494.     Else
  495.         FromVBar.Max = FromPict.Height - FromSwin.ScaleHeight
  496.         FromVBar.LargeChange = FromSwin.ScaleHeight
  497.         FromVBar.Enabled = True
  498.     End If
  499.     ' ToHBar.
  500.     ToHBar.Value = 0
  501.     If ToSwin.ScaleWidth >= ToPict.Width Then
  502.         ToHBar.Enabled = False
  503.     Else
  504.         ToHBar.Max = ToPict.Width - ToSwin.ScaleWidth
  505.         ToHBar.LargeChange = ToSwin.ScaleWidth
  506.         ToHBar.Enabled = True
  507.     End If
  508.     ' ToVBar.
  509.     ToVBar.Value = 0
  510.     If ToSwin.ScaleHeight >= ToPict.Height Then
  511.         ToVBar.Enabled = False
  512.     Else
  513.         ToVBar.Max = ToPict.Height - ToSwin.ScaleHeight
  514.         ToVBar.LargeChange = ToSwin.ScaleHeight
  515.         ToVBar.Enabled = True
  516.     End If
  517. End Sub
  518. ' ************************************************
  519. ' Subtract ToPict from FromPict and show the
  520. ' result in ToPict.
  521. ' ************************************************
  522. Sub SubtractFromOriginal()
  523. Const FACTOR1 = 1#
  524. Const FACTOR2 = 1# + FACTOR1
  525. Dim bm As BITMAP
  526. Dim hbm As Integer
  527. Dim status As Long
  528. Dim bytesin() As Byte
  529. Dim bytesout() As Byte
  530. Dim wid As Long
  531. Dim hgt As Long
  532. Dim X As Integer
  533. Dim Y As Integer
  534. Dim r As Long
  535. Dim g As Long
  536. Dim b As Long
  537.     ' *****************************
  538.     ' * Get the input bitmap data *
  539.     ' *****************************
  540.     ' Get a handle to the input bitmap.
  541.     hbm = FromPict.Image
  542.     ' See how big it is.
  543.     status = GetObject(hbm, BITMAP_SIZE, bm)
  544.     wid = bm.bmWidthBytes
  545.     hgt = bm.bmHeight
  546.     ' Get the bits.
  547.     ReDim bytesin(1 To wid, 1 To hgt)
  548.     status = GetBitmapBits(hbm, wid * hgt, bytesin(1, 1))
  549.     ' Get the current output bits.
  550.     ReDim bytesout(1 To wid, 1 To hgt)
  551.     status = GetBitmapBits(ToPict.Image, wid * hgt, bytesout(1, 1))
  552.     ' ************
  553.     ' * Subtract *
  554.     ' ************
  555.     For Y = 1 To hgt
  556.         For X = 1 To wid
  557.             With palentry(bytesin(X, Y))
  558.                 r = FACTOR2 * .peRed - FACTOR1 * palentry(bytesout(X, Y)).peRed
  559.                 g = FACTOR2 * .peGreen - FACTOR1 * palentry(bytesout(X, Y)).peGreen
  560.                 b = FACTOR2 * .peBlue - FACTOR1 * palentry(bytesout(X, Y)).peBlue
  561.             End With
  562.             If r < 0 Then r = 0
  563.             If g < 0 Then g = 0
  564.             If b < 0 Then b = 0
  565.             bytesout(X, Y) = GetNearestPaletteIndex( _
  566.                 LogPal, RGB(r, g, b) + &H2000000)
  567.         Next X
  568.     Next Y
  569.     ' **********************
  570.     ' * Display the output *
  571.     ' **********************
  572.     status = SetBitmapBits(ToPict.Image, wid * hgt, bytesout(1, 1))
  573.     ToPict.Refresh
  574. End Sub
  575. ' ***********************************************
  576. ' Give the form and all the picture boxes an
  577. ' hourglass cursor.
  578. ' ***********************************************
  579. Sub WaitStart()
  580.     MousePointer = vbHourglass
  581.     FromPict.MousePointer = vbHourglass
  582.     ToPict.MousePointer = vbHourglass
  583.     DoEvents
  584. End Sub
  585. ' ***********************************************
  586. ' Restore the mouse pointers for the form and all
  587. ' the picture boxes.
  588. ' ***********************************************
  589. Sub WaitEnd()
  590.     MousePointer = vbDefault
  591.     FromPict.MousePointer = vbDefault
  592.     ToPict.MousePointer = vbDefault
  593. End Sub
  594. ' ************************************************
  595. ' Apply the selected filter to FromPict.
  596. ' ************************************************
  597. Private Sub CmdApply_Click()
  598. Static btn_caption As String
  599. Dim fil As New Filter
  600.     ' If the filter is running, stop it.
  601.     If OperationRunning Then
  602.         ' Set a flag so the filter will stop.
  603.         OperationRunning = False
  604.         
  605.         ' Disable this button.
  606.         CmdApply.Enabled = False
  607.         CmdApply.Caption = "Stopping"
  608.         Exit Sub
  609.     End If
  610.     ' Make sure something is selected.
  611.     If FilterCombo.ListIndex < 0 Then
  612.         Beep
  613.         Exit Sub
  614.     End If
  615.     ' Otherwise start the filter running.
  616.     OperationRunning = True
  617.     btn_caption = CmdApply.Caption
  618.     CmdApply.Caption = "Stop"
  619.     CmdCopy.Enabled = False
  620.     WaitStart
  621.     Select Case FilterCombo.List(FilterCombo.ListIndex)
  622.         Case "Low Pass 3x3"
  623.             fil.InitializeLowPass 3
  624.         
  625.         Case "Low Pass 5x5"
  626.             fil.InitializeLowPass 5
  627.         
  628.         Case "Low Pass 7x7"
  629.             fil.InitializeLowPass 7
  630.     End Select
  631.     ' Apply the filter.
  632.     fil.ApplyFilter FromPict, ToPict, _
  633.         (ProgressCheck.Value = vbChecked)
  634.     ' Subtract the result from the original image.
  635.     SubtractFromOriginal
  636.     ' Reenable this button.
  637.     CmdApply.Caption = btn_caption
  638.     CmdApply.Enabled = True
  639.     CmdCopy.Enabled = True
  640.     OperationRunning = False
  641.     WaitEnd
  642.     ' This could have taken a long time so wake
  643.     ' the user up.
  644.     Beep
  645. End Sub
  646. ' ************************************************
  647. ' Copy ToPict into FromPict.
  648. ' ************************************************
  649. Private Sub CmdCopy_Click()
  650.     FromPict.PaintPicture ToPict.Image, 0, 0
  651.     DataChanged = True
  652. End Sub
  653. ' ***********************************************
  654. ' 1. Make sure we can handle palettes.
  655. ' 2. Find out how big the system palette is and how
  656. ' many static colors there are.
  657. ' 3. Load and display the system palette.
  658. ' ***********************************************
  659. Private Sub Form_Load()
  660.     ' Make sure the screen supports palettes.
  661.     If Not GetDeviceCaps(hdc, RASTERCAPS) And RC_PALETTE Then
  662.         Beep
  663.         MsgBox "This monitor does not support palettes.", _
  664.             vbCritical
  665.         End
  666.     End If
  667.     ' Get system palette size and # static colors.
  668.     SysPalSize = GetDeviceCaps(hdc, SIZEPALETTE)
  669.     NumStaticColors = GetDeviceCaps(hdc, NUMRESERVED)
  670.     StaticColor1 = NumStaticColors \ 2 - 1
  671.     StaticColor2 = SysPalSize - NumStaticColors \ 2
  672.     ' Remove the borders from the drawing areas.
  673.     FromPict.BorderStyle = vbTransparent
  674.     ToPict.BorderStyle = vbTransparent
  675.     ' Load the filter choices.
  676.     LoadFilterChoices
  677. End Sub
  678. ' ***********************************************
  679. ' Refuse to unload if there are unsaved changes.
  680. ' ***********************************************
  681. Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
  682.     Cancel = Not DataSafe()
  683. End Sub
  684. ' ***********************************************
  685. ' Make the picture as large as possible.
  686. ' ***********************************************
  687. Private Sub Form_Resize()
  688. Const GAP = 4
  689. Dim hgt As Single
  690. Dim wid As Single
  691.     If WindowState = vbMinimized Then Exit Sub
  692.     hgt = ScaleHeight - FromHBar.Height - 1
  693.     wid = (ScaleWidth - ProgressCheck.Width - 1 - _
  694.         2 * GAP - 2 * FromVBar.Width - 2) / 2
  695.     ' Place FromSwin and its scroll bars.
  696.     FromSwin.Move 0, 0, wid, hgt
  697.     FromVBar.Move _
  698.         FromSwin.Left + FromSwin.Width + 1, _
  699.         0, FromVBar.Width, hgt
  700.     FromHBar.Move _
  701.         FromSwin.Left, FromSwin.Height + 1, _
  702.         wid
  703.     ' Place the command buttons and stuff.
  704.     ProgressCheck.Left = (ScaleWidth - ProgressCheck.Width) / 2
  705.     FilterCombo.Left = (ScaleWidth - FilterCombo.Width) / 2
  706.     CmdApply.Left = (ScaleWidth - CmdApply.Width) / 2
  707.     CmdCopy.Left = (ScaleWidth - CmdCopy.Width) / 2
  708.     ' Place ToSwin and its scroll bars.
  709.     ToSwin.Move ProgressCheck.Left + _
  710.         ProgressCheck.Width + GAP, 0, wid, hgt
  711.     ToVBar.Move _
  712.         ToSwin.Left + ToSwin.Width + 1, _
  713.         0, ToVBar.Width, hgt
  714.     ToHBar.Move _
  715.         ToSwin.Left, ToSwin.Height + 1, _
  716.         wid
  717.     ' Set the scroll bar limits.
  718.     ResetScrollBars
  719. End Sub
  720. Private Sub Form_Unload(Cancel As Integer)
  721.     End
  722. End Sub
  723. ' ***********************************************
  724. ' Move FromPict within FromSwin.
  725. ' ***********************************************
  726. Private Sub FromHBar_Change()
  727.     FromPict.Left = -FromHBar.Value
  728. End Sub
  729. ' ***********************************************
  730. ' Move FromPict within FromSwin.
  731. ' ***********************************************
  732. Private Sub FromHBar_Scroll()
  733.     FromPict.Left = -FromHBar.Value
  734. End Sub
  735. ' ***********************************************
  736. ' Load a new image file.
  737. ' ***********************************************
  738. Private Sub mnuFileLoad_Click()
  739. Dim fname As String
  740.     ' Make sure any changes have been saved.
  741.     If Not DataSafe() Then Exit Sub
  742.     ' Allow the user to pick a file.
  743.     On Error Resume Next
  744.     FileDialog.filename = "*.BMP;*.ICO;*.RLE;*.WMF;*.DIB"
  745.     FileDialog.Flags = cdlOFNFileMustExist + cdlOFNHideReadOnly
  746.     FileDialog.ShowOpen
  747.     If Err.Number = cdlCancel Then
  748.         Exit Sub
  749.     ElseIf Err.Number <> 0 Then
  750.         Beep
  751.         MsgBox "Error selecting file.", , vbExclamation
  752.         Exit Sub
  753.     End If
  754.     On Error GoTo 0
  755.     fname = Trim$(FileDialog.filename)
  756.     FileDialog.InitDir = Left$(fname, Len(fname) _
  757.         - Len(FileDialog.FileTitle) - 1)
  758.     ' Load the picture.
  759.     WaitStart
  760.     LoadFromPict fname
  761.     WaitEnd
  762. End Sub
  763. ' ***********************************************
  764. ' Reload the file.
  765. ' ***********************************************
  766. Private Sub mnuFileRevert_Click()
  767.     ' If the data has changed, get confirmation.
  768.     If DataChanged Then
  769.         If MsgBox("The data has been modified. Are you sure you want to remove the changes?", _
  770.             vbQuestion + vbYesNo) = vbNo Then _
  771.                 Exit Sub
  772.     End If
  773.     ' Reload the picture.
  774.     WaitStart
  775.     DoEvents
  776.     LoadFromPict FileLoaded
  777.     WaitEnd
  778. End Sub
  779. ' ***********************************************
  780. ' Save the image in the file from which it was
  781. ' loaded.
  782. ' ***********************************************
  783. Private Sub mnuFileSave_Click()
  784.     WaitStart
  785.     DoEvents
  786.     SaveFromPict FileLoaded
  787.     WaitEnd
  788. End Sub
  789. ' ***********************************************
  790. ' Save the image in a new file.
  791. ' ***********************************************
  792. Private Sub mnuFileSaveAs_Click()
  793. Dim fname As String
  794.     ' Allow the user to pick a file.
  795.     On Error Resume Next
  796.     FileDialog.filename = "*.BMP;*.ICO;*.RLE;*.WMF;*.DIB"
  797.     FileDialog.Flags = cdlOFNOverwritePrompt + _
  798.         cdlOFNHideReadOnly + cdlOFNPathMustExist
  799.     FileDialog.ShowSave
  800.     If Err.Number = cdlCancel Then
  801.         Exit Sub
  802.     ElseIf Err.Number <> 0 Then
  803.         Beep
  804.         MsgBox "Error selecting file.", , vbExclamation
  805.         Exit Sub
  806.     End If
  807.     On Error GoTo 0
  808.     fname = Trim$(FileDialog.filename)
  809.     FileDialog.InitDir = Left$(fname, Len(fname) _
  810.         - Len(FileDialog.FileTitle) - 1)
  811.     ' Save the picture.
  812.     WaitStart
  813.     DoEvents
  814.     SaveFromPict fname
  815.     WaitEnd
  816. End Sub
  817. ' ***********************************************
  818. ' Save the picture in the indicated file.
  819. ' ***********************************************
  820. Sub SaveFromPict(fname As String)
  821.     On Error GoTo SaveError
  822.     SavePicture FromPict.Picture, fname
  823.     Caption = "Unsharp [" & fname & "]"
  824.     FileLoaded = fname
  825.     DataChanged = False
  826.     Exit Sub
  827. SaveError:
  828.     Beep
  829.     MsgBox "Error saving picture in file " & _
  830.         fname & "." & vbCrLf & vbCrLf & _
  831.         Error$, , vbExclamation
  832.     Exit Sub
  833. End Sub
  834. ' ***********************************************
  835. ' End the application. (See also the QueryUnload
  836. ' event.)
  837. ' ***********************************************
  838. Private Sub mnuFileExit_Click()
  839.     Unload Me
  840. End Sub
  841. ' ***********************************************
  842. ' Move FromPict within FromSwin.
  843. ' ***********************************************
  844. Private Sub FromVBar_Change()
  845.     FromPict.Top = -FromVBar.Value
  846. End Sub
  847. ' ***********************************************
  848. ' Move FromPict within FromSwin.
  849. ' ***********************************************
  850. Private Sub FromVBar_Scroll()
  851.     FromPict.Top = -FromVBar.Value
  852. End Sub
  853. ' ***********************************************
  854. ' Move ToPict within ToSwin.
  855. ' ***********************************************
  856. Private Sub ToHBar_Change()
  857.     ToPict.Left = -ToHBar.Value
  858. End Sub
  859. ' ***********************************************
  860. ' Move ToPict within ToSwin.
  861. ' ***********************************************
  862. Private Sub ToHBar_Scroll()
  863.     ToPict.Left = -ToHBar.Value
  864. End Sub
  865. ' ***********************************************
  866. ' Move ToPict within ToSwin.
  867. ' ***********************************************
  868. Private Sub ToVBar_Change()
  869.     ToPict.Top = -ToVBar.Value
  870. End Sub
  871. ' ***********************************************
  872. ' Move ToPict within ToSwin.
  873. ' ***********************************************
  874. Private Sub ToVBar_Scroll()
  875.     ToPict.Top = -ToVBar.Value
  876. End Sub
  877.